home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
soundhax.zip
/
REC_CD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-19
|
8KB
|
376 lines
/*-------------------------------------------------------*/
/* Originally part of SOUNDHAX v1 by John M. Trindle */
/* FREEWARE 12/19/91 */
/*-------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#define MULTIPLEX_INT 0x2f
#define INIT_MP_INT 0x1500;
#define CDREQ_MP_INT 0x1510;
#define STAT_HAS_AN_ERROR 0x8000
#define STAT_BUSY 0x0200
#define STAT_DONE 0x0100
int CDRomLoaded,CDRomDrive;
#define CD_EJECT_COMMAND 0
#define CD_SEEK_COMMAND 131
#define CD_PLAY_COMMAND 132
#define CD_STOP_COMMAND 133
#define CD_RESUME_COMMAND 136
#define READ_IOCTL_COMMAND 3
#define WRITE_IOCTL_COMMAND 12
#define CD_STATUS_COMMAND 6
#define GET_AUDIO_DISKINFO 10
#define GET_AUDIO_TRACKINFO 11
#define ADDR_HSG 0
#define ADDR_RED 1
#define CMS_AVAILABLE 1
#define FM_AVAILABLE 2
#define CV_AVAILABLE 4
#define OFF 0
#define ON 1
#define FALSE 0
#define TRUE 1
extern _ct_io_addx;
extern _ct_int_num;
extern _ct_music_status;
extern _ct_voice_status;
static int StatusWord;
typedef struct
{
unsigned char ParamLength;
unsigned char SubUnit;
unsigned char CommandCode;
int Status;
unsigned long Reserved1;
unsigned long Reserved2;
unsigned char AddressMode;
void *BeginPointer;
unsigned long Length;
unsigned long Reserved3;
} CDCmdStru;
typedef struct
{
unsigned char CommandCode;
unsigned char TrackNumber;
unsigned long StartAddress;
unsigned char Control;
} CDTrackInfoStru;
typedef struct
{
unsigned char CommandCode;
} CDEjectStru;
typedef struct
{
unsigned char CommandCode;
unsigned long Status;
} CDStatusStru;
typedef struct
{
unsigned char AddrMode;
unsigned long FrameOffset;
unsigned long NumberFrames;
} CDPlayStru;
typedef struct DiskInfo_Rec {
unsigned char CommandCode;
unsigned char LoTrack;
unsigned char HiTrack;
unsigned long LeadOut;
} CDDiskInfoStru;
CDCmdStru CDCmdBlock;
CDTrackInfoStru TrackInfo[100];
CDDiskInfoStru DiskInfo;
SendCDCommand(int CommandCode, void *BeginPtr, long Length);
unsigned long CDTrackInfo(int TrackNumber, int Minutes,
int Seconds, int Frames);
CDPlay(long Offset,long NumFrames);
unsigned int CDStatus();
PrintTimeFrames(long NumFrames);
unsigned long Red2HSG(unsigned long RedValue);
long LastSector;
int NumTracks;
main(int argc, char *argv[])
{
int i,j,DriverFeatures=0;
int Track,StartMin,StartSec,EndMin,EndSec,StartFrame,EndFrame;
long StartSector,EndSector;
FILE *outfp;
float TempFloat;
char LocalBuffer[132];
if (!CheckCD2F())
{
printf("MSCDEX NOT LOADED\n");
exit(1);
}
CDGetDiskInfo();
LastSector = DiskInfo.LeadOut;
NumTracks = DiskInfo.HiTrack-DiskInfo.LoTrack+1;
printf("Reading Drive %c\n",CDRomDrive+'A');
if (argc > 1)
{
Track = atoi(argv[1]);
printf("Starting Track %d, %d tracks on disk\n",Track,NumTracks);
}
else
{
for (i = DiskInfo.LoTrack; i <= DiskInfo.HiTrack; i++)
{
CDTrackInfo(i,0,0,0);
}
TrackInfo[DiskInfo.HiTrack+1].StartAddress = DiskInfo.LeadOut;
for (i = DiskInfo.LoTrack; i <= DiskInfo.HiTrack; i++)
{
printf("Track %2d ",i);
PrintTimeFrames(Red2HSG(TrackInfo[i+1].StartAddress)-Red2HSG(TrackInfo[i].StartAddress));
printf("\n");
}
}
if (argc < 2)
{
exit(0);
}
outfp = NULL;
EndSector = Red2HSG(DiskInfo.LeadOut)-150L; /* 150L Fudge Factor */
StartMin = 0;
StartSec = 0;
StartFrame = 0;
EndMin = 0;
EndSec = 0;
EndFrame = 0;
if (argc > 2)
{
strcpy(LocalBuffer,argv[2]);
StartMin = atoi(strtok(LocalBuffer,":"));
TempFloat = atof(strtok(NULL,":"));
StartSec = (int) TempFloat;
StartFrame = ((int)(TempFloat*75))-StartSec*75;
}
StartSector = CDTrackInfo(Track,StartMin,StartSec,StartFrame);
if (argc > 3)
{
strcpy(LocalBuffer,argv[3]);
EndMin = atoi(strtok(LocalBuffer,":"));
TempFloat = atof(strtok(NULL,":"));
EndSec = (int) TempFloat;
EndFrame = ((int)(TempFloat*75))-EndSec*75;
EndSector = CDTrackInfo(Track,EndMin,EndSec,EndFrame);
}
CDStop();
if (argc > 4)
{
_ct_io_addx = 0x220; /* I/O Base */
DriverFeatures = _ct_card_here();
if (DriverFeatures & CV_AVAILABLE)
{
_sbc_scan_int();
_ctvd_init(6);
printf("opening file %s\n",argv[4]);
outfp = fopen(argv[4],"wb");
_ctvd_speaker(OFF);
_ctvd_input(outfp->_file,250);
}
}
CDPlay(StartSector,EndSector-StartSector);
if (outfp != NULL)
{
printf("Press any key to abort\n");
/* This could be keyed on CDStatus BUSY, but corrupts sample */
while(TRUE)
{
if (kbhit())
{
getch();
CDStop();
break;
}
}
}
printf("\n");
if (outfp != NULL)
fclose(outfp);
if (DriverFeatures & CV_AVAILABLE && argc > 4)
_ctvd_terminate();
}
CheckCD2F()
{
union REGS regs;
regs.x.ax = INIT_MP_INT;
int86(MULTIPLEX_INT,®s,®s);
CDRomLoaded = regs.x.bx;
CDRomDrive = regs.x.cx;
}
CDEject()
{
CDEjectStru EjectRequestBlock;
EjectRequestBlock.CommandCode = CD_EJECT_COMMAND;
SendCDCommand(WRITE_IOCTL_COMMAND,&EjectRequestBlock,sizeof(CDEjectStru));
}
unsigned int CDStatus()
{
unsigned int RetVal;
CDStatusStru StatusRequestBlock;
StatusRequestBlock.CommandCode = CD_STATUS_COMMAND;
RetVal = SendCDCommand(READ_IOCTL_COMMAND,&StatusRequestBlock,sizeof(CDStatusStru));
return(RetVal);
}
CDStop()
{
return(SendCDCommand(CD_STOP_COMMAND,NULL,0));
}
CDResume()
{
return(SendCDCommand(CD_RESUME_COMMAND,NULL,0));
}
CDPlay(long FrameOffset, long NumFrames)
{
SendCDCommand(CD_PLAY_COMMAND,(void *)FrameOffset,NumFrames);
}
CDGetDiskInfo()
{
DiskInfo.CommandCode = GET_AUDIO_DISKINFO;
SendCDCommand(READ_IOCTL_COMMAND,&DiskInfo,sizeof(CDDiskInfoStru));
}
PrintTimeFrames(long NumFrames)
{
long Mins;
long Secs;
long PlusFrames;
PlusFrames = NumFrames;
Secs = PlusFrames/75;
PlusFrames -= Secs*75;
Mins = Secs/60;
Secs -= Mins*60;
printf("%2ld:%02ld:%02ld",Mins,Secs,PlusFrames);
}
SendCDCommand(int CommandCode, void *BeginPtr, long Length)
{
union REGS regs;
struct SREGS sregs;
CDCmdBlock.ParamLength = 13;
CDCmdBlock.SubUnit = 0;
CDCmdBlock.CommandCode = CommandCode;
CDCmdBlock.Status = 0;
CDCmdBlock.AddressMode = ADDR_HSG;
CDCmdBlock.BeginPointer = BeginPtr;
CDCmdBlock.Length = Length;
CDCmdBlock.Reserved3 = 0;
regs.x.ax = CDREQ_MP_INT;
regs.x.bx = FP_OFF(&CDCmdBlock);
regs.x.cx = CDRomDrive;
sregs.es = FP_SEG(&CDCmdBlock);
int86x(MULTIPLEX_INT,®s,®s,&sregs);
return(CDCmdBlock.Status);
}
unsigned long CDTrackInfo(int TrackNumber, int Minutes, int Seconds, int Frames)
{
TrackInfo[TrackNumber].CommandCode = GET_AUDIO_TRACKINFO;
TrackInfo[TrackNumber].TrackNumber = TrackNumber;
SendCDCommand(READ_IOCTL_COMMAND,&(TrackInfo[TrackNumber]),sizeof(CDTrackInfoStru));
return(Red2HSG(TrackInfo[TrackNumber].StartAddress)+(Minutes*60L+((long)Seconds))*75L+((long)Frames));
}
unsigned long Red2HSG(unsigned long RedValue)
{
unsigned long Mins;
unsigned long Secs;
unsigned long PlusFrames;
PlusFrames = RedValue & 0x000000ffL;
Secs = ((RedValue & 0x0000ff00L) >> 8);
Mins = ((RedValue & 0x00ff0000L) >> 16);
return((Mins*60+Secs)*75+PlusFrames);
}